package cc.rengu.oltp.service.realize.impl;

import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.enums.PinTypeEnum;
import cc.rengu.oltp.service.realize.HsmService;
import cc.rengu.oltp.utility.util.*;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;

import java.lang.reflect.Method;

/**
 * 加密平台接口调用实现类
 * Created by wangcheng on 2021/3/26 11:33
 */
public class HsmServiceImpl implements HsmService {
    RgLogger rglog = RgLog.getLogger(this.getClass().getName());
    private boolean apiCallFlag = false;
    private Class clasz;
    private Object methodInstance;

    public HsmServiceImpl() throws Exception {
        String hsmServiceImpl = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.APPLICATION_CONF_NODE, AppConfigConstant.HSM_SERVICE_IMPL);
        String DEFAULT_IMPL = "cc.rengu.oltp.service.realize.impl.HsmServiceImpl";
        if (!StringUtil.isEmptyOrNull(hsmServiceImpl) && !DEFAULT_IMPL.equals(hsmServiceImpl.trim())) {
            apiCallFlag = true;
            clasz = Class.forName(hsmServiceImpl.trim());
            methodInstance = clasz.newInstance();
        }
    }

    @Override
    public String[] hsmGenerateTmkByZmk(String instId, String keyTag) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmGenerateTmkByZmk", String.class, String.class);
            return (String[]) callMethod.invoke(methodInstance, instId, keyTag);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return new String[]{"00000000000000001111111111111111", "FFFFFFFFFFFFFFFF"};
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String[] hsmGenerateTpkByTmk(String instId, String keyTag) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmGenerateTpkByTmk", String.class, String.class);
            return (String[]) callMethod.invoke(methodInstance, instId, keyTag);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return new String[]{"00000000000000001111111111111111", "FFFFFFFFFFFFFFFF"};
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String[] hsmGenerateTakByTmk(String instId, String keyTag) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmGenerateTakByTmk", String.class, String.class);
            return (String[]) callMethod.invoke(methodInstance, instId, keyTag);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return new String[]{"00000000000000001111111111111111", "FFFFFFFFFFFFFFFF"};
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmGenerateMac(String instId, String keyTag, String macBlockData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmGenerateMac", String.class, String.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, keyTag, macBlockData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return "FFFFFFFF";
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmGenerateSignString(String instId, String certKey, String signBlock, String algorithmType) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmGenerateSignString", String.class, String.class, String.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, certKey, signBlock, algorithmType);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的签名实现方式，且勿带上生产!");
                return MD5Util.generateSignString(signBlock, "&key=", certKey);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public boolean hsmVerifySignString(String instId, String certKey, String signBlock, String algorithmType, String signData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmVerifySignString", String.class, String.class, String.class, String.class, String.class);
            return (boolean) callMethod.invoke(methodInstance, instId, certKey, signBlock, algorithmType, signData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的签名验签实现方式，且勿带上生产!");
                String signString = MD5Util.generateSignString(signBlock, "&key=", certKey);
                if (!StringUtil.isEmptyOrNull(signString) && !StringUtil.isEmptyOrNull(signData)) {
                    return signString.equals(signData);
                } else {
                    rglog.error("签名验签失败,系统生成签名:<{}>,待验证签名:<{}>", signString, signData);
                    return false;
                }
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmEncryptData(String instId, String keyTag, String algorithmType, String data) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmEncryptData", String.class, String.class, String.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, keyTag, algorithmType, data);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.pkcs5EcbEncryptData("00000000000000001111111111111111", data);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmDecryptData(String instId, String keyTag, String algorithmType, String data) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmDecryptData", String.class, String.class, String.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, keyTag, algorithmType, data);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.pkcs5EcbDecryptData("00000000000000001111111111111111", data);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmGeneratePinOffset(String instId, String srcKeyTag, String dstKeyTag, String acctNo, PinTypeEnum pinType, String pinData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmGeneratePinOffset", String.class, String.class, String.class, String.class, PinTypeEnum.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, srcKeyTag, dstKeyTag, acctNo, pinType, pinData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return RandomUtil.randomNumStr(6);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public boolean hsmVerifyPin(String instId, String srcKeyTag, String dstKeyTag, String acctNo, PinTypeEnum pinType, String pinData, String pinCheckValue) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmVerifyPin", String.class, String.class, String.class, String.class, PinTypeEnum.class, String.class, String.class);
            return (boolean) callMethod.invoke(methodInstance, instId, srcKeyTag, dstKeyTag, acctNo, pinType, pinData, pinCheckValue);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return true;
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmModifyPin(String instId, String srcKeyTag, String dstKeyTag, String acctNo, PinTypeEnum pinType, String pinData, String pinCheckValue, String newPinData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmModifyPin", String.class, String.class, String.class, String.class, PinTypeEnum.class, String.class, String.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, srcKeyTag, dstKeyTag, acctNo, pinType, pinData, pinCheckValue, newPinData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.generateAesKey(32);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmTranslatePin(String instId, String srcKeyTag, String dstKeyTag, String srcAcctNo, String dstAcctNo, String pinData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmTranslatePin", String.class, String.class, String.class, String.class, String.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, srcKeyTag, dstKeyTag, srcAcctNo, dstAcctNo, pinData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.generateAesKey(32);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmTransPinRsaToDes(String instId, String srckeyTag, String dstKeyTag, String acctNo, PinTypeEnum pinType, String pinData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmTransPinRsaToDes", String.class, String.class, String.class, String.class, PinTypeEnum.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, srckeyTag, dstKeyTag, acctNo, pinType, pinData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.generateAesKey(32);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmTransPinSm2ToDes(String instId, String srckeyTag, String dstKeyTag, String acctNo, PinTypeEnum pinType, String pinData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmTransPinSm2ToDes", String.class, String.class, String.class, String.class, PinTypeEnum.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, srckeyTag, dstKeyTag, acctNo, pinType, pinData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.generateAesKey(32);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmTransPinDesToRsa(String instId, String srckeyTag, String dstKeyTag, String acctNo, PinTypeEnum pinType, String pinData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmTransPinDesToRsa", String.class, String.class, String.class, String.class, PinTypeEnum.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, srckeyTag, dstKeyTag, acctNo, pinType, pinData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.generateAesKey(32);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmTransPinDesToSm2(String instId, String srckeyTag, String dstKeyTag, String acctNo, PinTypeEnum pinType, String pinData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmTransPinDesToSm2", String.class, String.class, String.class, String.class, PinTypeEnum.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, srckeyTag, dstKeyTag, acctNo, pinType, pinData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.generateAesKey(32);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }

    @Override
    public String hsmTransPinZpkToPvk(String instId, String srcKeyTag, String dstKeyTag, String srcAcctNo, String dstAcctNo, PinTypeEnum pinType, String pinData) throws Exception {
        if (apiCallFlag) {
            Method callMethod = clasz.getMethod("hsmTransPinZpkToPvk", String.class, String.class, String.class, String.class, String.class, PinTypeEnum.class, String.class);
            return (String) callMethod.invoke(methodInstance, instId, srcKeyTag, dstKeyTag, srcAcctNo, dstAcctNo, pinType, pinData);
        } else {
            if (AppParamConstant.DEFAULT_ENV.equals(AppParamConstant.APPLICATION_ENV)) {
                rglog.error("未配置加密平台调用实现类，使用系统简单的加解密实现方式，且勿带上生产!");
                return AESUtil.generateAesKey(32);
            } else {
                rglog.error("未配置加密平台调用实现类或者配置的实现类不存在，请检查applicationConfig.xml中的配置!");
                throw new Exception("未配置加密平台调用实现类或者配置的实现类不存在!");
            }
        }
    }
}
